package com.nx.platform.es.biz.esspider.handler;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.nx.platform.es.biz.esspider.resource.DBManager;
import com.nx.platform.es.common.utils.MoreSplitters;
import com.nx.platform.es.biz.esspider.entity.Item;
import com.nx.platform.es.common.utils.MoreMaps;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * 逆向的订单
 * @author
 *
 */
@HandlerDefine(HandlerType.DB)
@Slf4j
public class DBTradeInTurn0FieldsHandler extends AbstractDBHandler {

    public DBTradeInTurn0FieldsHandler(String identity, DBManager dbManager) {
        super(identity, dbManager);
    }
    private static final Gson GSON = new Gson();
    private String sql;
    private String idField;
    private String[] field;
    private boolean toString;
    private boolean factors;

    @Override
    public void init(Map<?, ?> settings) throws Exception {
        sql = MoreMaps.getString(settings, "sql");
        idField = MoreMaps.getString(settings, "idField");
        field = MoreMaps.getStringArray(settings, "field", MoreSplitters.COMMA);
        toString = MoreMaps.getBooleanValue(settings, "toString", false);
        factors = MoreMaps.getBooleanValue(settings, "factors", false);
        Preconditions.checkNotNull(getJdbcTemplate());
        Preconditions.checkArgument(!Strings.isNullOrEmpty(sql), "sql null or empty");
        Preconditions.checkArgument(!Strings.isNullOrEmpty(idField), "idField null or empty");
    }

    @Override
    public void handle(Map<Long, Item> items) throws Exception {
        List<Long> orderIds = new ArrayList<>(items.size());
        List<Long> buyerIds = new ArrayList<>(items.size());
        Map<String, Item> map = new HashMap<>();
        for(Map.Entry<Long, Item> entry: items.entrySet()) {
            Long orderId = entry.getKey();
            // 将上一次查询结果中的sellerId作为这次查询的buyerId，查找反向的record
            Long buyerId = MoreMaps.getLong(entry.getValue().getDoc(), "seller_id");
            if (buyerId == null) {
                log.info("id={} desc=buyerId_null item={}", orderId, GSON.toJson(entry.getValue()));
                continue;
            }
            orderIds.add(orderId);
            buyerIds.add(buyerId);
            String k = String.format("%d", orderId);
            map.put(k, entry.getValue());
        }

        if (orderIds.size() == 0) {
            return;
        }
        Map<String, List<Long>> params = new HashMap<>();
        params.put("order_ids", orderIds);
        params.put("buyer_ids", buyerIds);
        List<Map<String, Object>> queryResults;
        try {
            queryResults = getJdbcTemplate().queryForList(sql, params);
        } catch (Exception e) {
            log.error("sql={}, param={}", sql, GSON.toJson(params));
            throw e;
        }
        log.debug("######queryResults={}", queryResults);
        // 更新文档
        for (Map<String, Object> queryResult : queryResults) {
            Long id = MoreMaps.getLong(queryResult, idField);
            if (id == null) {
                continue;
            }
            Item item = items.get(id);
            if (item == null) {
                continue;
            }
            Stream<String> fieldNames = field != null && field.length > 0 ? Stream.of(field) : queryResult.keySet().stream();
            fieldNames.forEach((String f) -> {
                Object fieldValue = queryResult.get(f);
                item.getDoc().put(f, fieldValue);
                String str = String.valueOf(fieldValue);
                if (factors && str.startsWith("{") && str.endsWith("}")) {
                    try {
                        DBSingleValueFieldsHandler.ScoresFields fields = GSON.fromJson(str, DBSingleValueFieldsHandler.ScoresFields.class);
                        if (fields != null) {
                            item.getDoc().putAll(fields.toMap());
                        }
                    } catch (Throwable e) {
                        log.warn("read json field failed, id={}, json={}", id, str, e);
                    }
                }
            });
        }
    }

}
